/**********************************************************

@description:
*File Name:log.c
*Author: ydx
*mail: yudongxiang93@163.com
*Create Time: Thu 05 Jun 2025 08:28:32 PM CST
**********************************************************/
#include "log.h"
#include "types.h"
#include "cpu_instr.h"
#include "serial.h"
#include <stdarg.h>
#include "klib.h"
#include "irq.h"
#include "mutex.h"
#include "console.h"
#include "dev.h"

#define LOG_USE_COM 0

static mutex_t mutex;

static int log_dev_id;

void serial_init(void)
{
    outb(COM1_PORT + 1, 0x00);    // disable the intrupt of the interface of serial
    outb(COM1_PORT + 3, 0x80);    // set the baud rate of the interface of serial
    outb(COM1_PORT + 0, 0x03);
    outb(COM1_PORT + 1, 0x00);
    outb(COM1_PORT + 3, 0x03);
    outb(COM1_PORT + 2, 0xC7);
    outb(COM1_PORT + 4, 0x0F);
}

void log_init(void)
{
    mutex_init(&mutex);
    log_dev_id = dev_open(DEV_TTY, 0, (void *)0);
#if LOG_USE_COM
    serial_init();
#endif
}
void log_printf(const char *fmt, ...)
{
    char str_buf[1024];
    kernel_memset(str_buf, '\0', sizeof(str_buf));

    va_list args;
    va_start(args, fmt);
    kernel_vsprintf(str_buf, fmt, args);
    va_end(args);

    // irq_state_t irq_state= irq_enter_protect();
    mutex_lock(&mutex);
#if LOG_USE_COM
    const char *p = str_buf;
    while (*p != '\0')
    {
        while ((inb(COM1_PORT + 5) & (1 << 6)) == 0)
            ;
        outb(COM1_PORT, *p++);
    }
    outb(COM1_PORT, '\r');
    outb(COM1_PORT, '\n');
#else
    // console_write(0,str_buf,kernel_strlen(str_buf));
    // console_write(0,"\n",1);
    dev_write(log_dev_id, 0, "log:", 4);
    dev_write(log_dev_id, 0, str_buf, kernel_strlen(str_buf));
    char ch = '\n';
    dev_write(log_dev_id, 0, &ch, 1);
#endif
    // irq_exit_protect(irq_state);
    mutex_unlock(&mutex);
}